using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization; 
using System.IO;
using System.Xml;
using System.Text;
using System;


public class LevelHandler : MonoBehaviour {
	
	private static LevelHandler instance;
 
	public static LevelHandler Instance
	{
		get
		{
			if (instance == null)
			{
				instance = new GameObject("Level").AddComponent<LevelHandler> ();
			}
 
			return instance;
		}
	}
	
 
	public void OnApplicationQuit ()
	{
		instance = null;
	}
	
	public Dictionary<int,GameObject> tangibles;
	public int nbUserObjects = 0;
	
	
	private string levelFilePath; 
	
	public Level currentLevel;
	
	void Awake(){
		tangibles = new Dictionary<int, GameObject>();
		
		levelFilePath = Application.dataPath+"/Resources/Levels/";
		FileInfo levelFile = new FileInfo(levelFilePath);
		levelFile.Directory.Create();

	}
	
	public void loadLevel(string fileName){	
		
		TextAsset xmlFile = (TextAsset) Resources.Load("Levels/"+fileName);  
		string data = xmlFile.text;
     	Level level = XmlUtils.DeserializeLevel(data);
		
		currentLevel = level;
		
		cleanLevel();
		
		StartCoroutine(createLevel(level));
		//createLevel(level);
	}
	
	public void saveLevel(string fileName){
		Level level_data = new Level(gameObject,fileName);
     	string result = XmlUtils.SerializeLevel(level_data); 
		XmlUtils.CreateXML(result,levelFilePath+fileName+".xml");
		
		Application.CaptureScreenshot(levelFilePath+fileName+"_thumb.png");
	}
	
	
	public IEnumerator createLevel(Level levelData){
		yield return new WaitForSeconds(0.1f);

		LevelConstants.allowPrimary = levelData.AllowPrimary;
		LevelConstants.allowSecondary = levelData.AllowSecondary;

		
		LevelConstants.maxFilter = levelData.MaxFilter;
		LevelConstants.maxMirror = levelData.MaxMirror;
		LevelConstants.maxMixer = levelData.MaxMixer;
		LevelConstants.maxDivider = levelData.MaxDivider;
		
		LevelConstants.nbReceivers = 0;
		LevelConstants.nbActivatedReceivers = 0;
		
		foreach(GPObject gpObj in levelData.GamePlayObjects){
			if(LevelConstants.editorMode){
				createObject(gpObj);
			}else{
				if(gpObj.Type == ObjectType.LaserGenerator || gpObj.Type == ObjectType.LaserReceiver || gpObj.IsFixed){
					createObject(gpObj);
				}
			}
		}
		
	}
	
	public GameObject createObject(GPObject gpo){
		if(!creationAllowed(gpo.Type)){
			
			//InfoDisplay.Instance.displayMessage("Vous ne pouvez plus ajouter de "+gpo.Type.ToString()+" !",2f);
			return null;
		}
		
		GameObject newGo = Instantiate(Resources.Load("Prefabs/"+gpo.Type)) as GameObject;
		newGo.transform.parent = transform;
		if(newGo.GetComponent<LightRayHandler>() != null){
			if(gpo.Type == ObjectType.LaserGenerator && !gpo.IsFixed){
				gpo.ObjColor = Color.white;	
			}
			newGo.GetComponent<LightRayHandler>().initialize(gpo.Id, gpo.Position,gpo.Rotation,gpo.ObjColor,gpo.IsFixed);
		}
		
		tangibles.Add(gpo.Id,newGo);
		
		return newGo;
	}
	
	public bool creationAllowed(ObjectType type){
		int current;
		int max;
		
		switch(type){
		case ObjectType.Filter:
			current = LevelConstants.nbFilter;
			max = LevelConstants.maxFilter;
			break;
		case ObjectType.Mirror:
			current = LevelConstants.nbMirror;
			max = LevelConstants.maxMirror;
			break;
		case ObjectType.Mixer:
			current = LevelConstants.nbMixer;
			max = LevelConstants.maxMixer;
			break;
		case ObjectType.Divider:
			current = LevelConstants.nbDivider;
			max = LevelConstants.maxDivider;
			break;
		default :
			return true;
		}
		
		return current < max;
	}
	
	public void cleanLevel(){
		tangibles.Clear();
		foreach(Transform child in transform){
			Destroy(child.gameObject);	
		}
	}
	
	public bool allCorrect(){
		foreach(GameObject obj in tangibles.Values){
			LightRayHandler lrh = obj.GetComponent<LightRayHandler>();
			if(lrh != null){
				if(lrh.Type != ObjectType.LaserGenerator && lrh.Type != ObjectType.LaserReceiver && lrh.Type != ObjectType.Unknown ){
					if(!lrh.CorrectPosition){
						return false;	
					}
				}
			}
		}
		
		return true;
	}
	
	
}
